#include "StdAfx.h"
#include "ClientManager.h"

CClientBase::CClientBase()
{
}

CClientBase::~CClientBase()
{
}

xgc_void CClientBase::AllocIdentify()
{
	ClientManager::Instance().AppendObject( this );
}

xgc_void CClientBase::DellocIdentify()
{
	ClientManager::Instance().RemoveObject( this );
}

CClientManager::CClientManager()
	: mCurrentOID(0)
	, mCurrentFree(0)
	, pObjectPool(xgc_nullptr)
{
}

CClientManager::~CClientManager(void)
{
}

xgc_bool CClientManager::Initialize( xgc_uint16 nPoolSize )
{
	mPoolSize = mCurrentFree = nPoolSize;
	pObjectPool = new CClientBase*[nPoolSize];

	return pObjectPool != xgc_nullptr;
}

CClientBase* CClientManager::FetchClient( xgc_uint16 OID )
{
	autolock locker( mGuard );
	CClientBase* pClient = pObjectPool[OID];
	pClient->Fetch();

	return pClient;
}

xgc_void CClientManager::FreeClient( CClientBase* pClient )
{
	pClient->Free();
}

xgc_void CClientManager::AppendObject( CClientBase* pObj )
{
	autolock locker( mGuard );
	xgc_uint16 OID = mCurrentOID;
	if( mCurrentFree == 0 )
		return;

	while( mCurrentFree && pObjectPool[mCurrentOID] )
	{
		OID = mCurrentOID++;
		if( mCurrentOID >= mPoolSize )
			mCurrentOID = 0;
	}
	mCurrentFree--;

	pObjectPool[OID] = pObj;
	pObj->OID = OID;
}

xgc_void CClientManager::RemoveObject( CClientBase* pObj )
{
	autolock locker( mGuard );

	ASSERT_RETURN( pObjectPool[pObj->OID] == pObj, xgc_void(0) );
	pObjectPool[pObj->OID] = 0;

	mCurrentFree++;

	ASSERT( mCurrentFree <= mPoolSize );
}
